﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.DomainServices.Client;
using System.Windows;

using GroupChallenge.Helpers;
using GroupChallenge.Web;
using GroupChallenge.Web.Services;

namespace GroupChallenge
{
    public class MainViewModel : INotifyPropertyChanged
    {
        #region Properties

        private GroupChallengeSvc.GroupChallengeClient _Client = null;
        public GroupChallengeSvc.GroupChallengeClient Client
        {
            get
            {
                if (null != _Client)
                {
                    if (_Client.State != System.ServiceModel.CommunicationState.Created &&
                        _Client.State != System.ServiceModel.CommunicationState.Opened)
                    {
                        _Client.Abort();
                        _Client = null;
                    }
                }

                if (null == _Client)
                {
                    string endpointConfigurationName = "BasicHttpBinding_IGroupChallenge";
                    string endpointUrl = string.Format("{0}/GroupChallenge/GroupChallenge.svc", Utils.GetHostUrl(false));

                    EndpointAddress endpointAddress = new EndpointAddress(endpointUrl);

                    _Client = new GroupChallengeSvc.GroupChallengeClient(endpointConfigurationName, endpointAddress);
                }

                return _Client;
            }
        }

        private ObservableCollection<PlayerImage> _PlayerImages = new ObservableCollection<PlayerImage>();
        public ObservableCollection<PlayerImage> PlayerImages
        {
            get { return _PlayerImages; }
            set
            {
                _PlayerImages = value;

                RaisePropertyChanged("PlayerImages");
            }
        }

        /// <summary>
        /// The <see cref="NickName" /> dependency property's name.
        /// </summary>
        private string _NickName = string.Empty;
        /// <summary>
        /// Gets or sets the value of the <see cref="NickName" /> property. This is a dependency property.
        /// </summary>
        public string NickName
        {
            get { return _NickName; }
            set
            {
                if (value != _NickName)
                {
                    _NickName = value;

                    RaisePropertyChanged("NickName");
                    RaisePropertyChanged("ValidNickName");
                    RaisePropertyChanged("PlayerTitle");
                    RaisePropertyChanged("PlayerScoreTitle");
                }
            }
        }

        public bool ValidNickName
        {
            get
            {
                // Return if the NickName is set indicating a valid Join game.
                return !string.IsNullOrEmpty(NickName);
            }
            private set { }
        }

        private string _FullName = string.Empty;
        public string FullName
        {
            get { return _FullName; }
            set
            {
                if (value != _FullName)
                {
                    _FullName = value;
                    RaisePropertyChanged("FullName");
                }
            }
        }

        private string _PlayerId = string.Empty;
        public string PlayerId
        {
            get { return _PlayerId; }
            set
            {
                if (value != _PlayerId)
                {
                    _PlayerId = value;
                    RaisePropertyChanged("PlayerId");
                }
            }
        }

        private int _Score = 0;
        public int Score
        {
            get { return _Score; }
            set
            {
                if (_Score != value)
                {
                    _Score = value;

                    RaisePropertyChanged("Score");
                    RaisePropertyChanged("PlayerScoreTitle");
                }
            }
        }

        public string PlayerTitle
        {
            get
            {
                string ret = "Group Challenge";

                if (!string.IsNullOrEmpty(NickName))
                {
                    ret += " - " + NickName;
                }

                return ret;
            }
            set
            {
                RaisePropertyChanged("PlayerTitle");
            }
        }

        public string PlayerScoreTitle
        {
            // Change raised form the score change.
            get
            {
                string ret = string.Empty;

                if (!string.IsNullOrEmpty(NickName))
                {
                    ret = "My Score: " + Score.ToString();
                }

                return ret;
            }
        }

        #endregion                              // Properties

        #region NotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(String propertyName)
        {
            if (null != PropertyChanged)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion                              // NotifyPropertyChanged

        #region Internal Methods

        internal void AddPlayerImage(PlayerImage entity)
        {
            if (null != entity)
            {
                entity.PlayerId = entity.GetPlayerIdFromFile(entity.ImageFileName);

                PlayerImages.Add(entity);
            }
        }

        internal void DeletePlayerImage(int playerImageId)
        {
            if (playerImageId < 1)
            {
                MessageBox.Show("Invalid player image id.  Unable to delete the player image.", "Delete Image Error", MessageBoxButton.OK);
            }
            else
            {
                try
                {
                    GroupChallengeDomainContext groupChallengeDomainContext = new GroupChallengeDomainContext();

                    var query = groupChallengeDomainContext.DeletePlayerImageQuery(playerImageId);
                    groupChallengeDomainContext.Load(query, CompletedDeletePlayerImage, true);
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show("Unable to delete the player image.\r\n\r\nReason: " + ex.Message, "Delete Image Error", MessageBoxButton.OK);
                }
            }
        }

        private void CompletedDeletePlayerImage(LoadOperation loadOperation)
        {
            if (loadOperation.HasError)
            {
                loadOperation.MarkErrorAsHandled();

                MessageBox.Show("Invalid player image id.  Unable to delete the player image.\r\n\r\nReason: " + loadOperation.Error.Message, "Delete Image Error", MessageBoxButton.OK);
            }
            else
            {
                if (null != loadOperation.Entities)
                {
                    FriendlyResult friendlyResult = loadOperation.Entities.FirstOrDefault() as FriendlyResult;
                    if (null != friendlyResult)
                    {
                        if (friendlyResult.ResultId == 1)
                        {
                            MessageBox.Show(friendlyResult.FriendlyText, "Deleted Player Image", MessageBoxButton.OK);
                        }
                        else
                        {
                            MessageBox.Show(friendlyResult.FriendlyText, "Delete Player Image Error", MessageBoxButton.OK);
                        }
                    }
                }
            }
        }

        #endregion                              // Internal Methods
    }
}